/* Copyright 2008 Bas van den Berg
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "PlayerCreationSession.h"
#include "Connection.h"
#include "Database.h"
#include "Utils.h"
#include "config.h"
#include "myassert.h"
#include "MudPlayer.h"

using namespace Chronos;

PlayerCreationSession::PlayerCreationSession(Connection* con, Database& db_)
        : prompt("name: ")
        , state(NAME)
		, connection(con)
		, timeout(Config::LOGIN_TIMEOUT)
		, retries(3)
        , database(db_)
{
    connection->write("Welcome to Character Creation\n");
    printPrompt();
}


PlayerCreationSession::~PlayerCreationSession() {
    if (state != DONE) delete connection;
}


int PlayerCreationSession::handlePulse() {
    ASSERT_NOT_EQUAL(DONE, state);
    if (timeout == 0) {
		connection->write("(timeout)\n");
		return FAIL;
	}
    --timeout;

    int size = connection->read(readBuffer, MAX_INPUT_LENGTH);
    if (size == Connection::ERROR) return FAIL;
    if (size == Connection::NODATA) return INPROGRESS;

    size = Utils::stripNewline(readBuffer);
    if (size == 0) {
        if (--retries == 0) return FAIL;
        printPrompt();
        timeout = Config::LOGIN_TIMEOUT;
        return INPROGRESS;
    }

    if (readBuffer[0] == -1) return INPROGRESS;    // TERM chars?
    timeout = Config::LOGIN_TIMEOUT;

    switch (state) {
    case NAME:
        if (database.hasPlayer(readBuffer)) {
            if (--retries == 0) return FAIL;
            connection->write("A player with that name already exists.\n");
            printPrompt();
            break;
        }
        name = readBuffer;
        state = PASSWORD;
        setPrompt("password: ");
        printPrompt();
        connection->setEcho(false);
        retries = 3;
        break;
    case PASSWORD:
        connection->setEcho(true);
        password = readBuffer;
        state = PASSWORD_CONFIRM;
        setPrompt("confirm password: ");
        printPrompt();
        connection->setEcho(false);
        retries = 3;
        break;
    case PASSWORD_CONFIRM:
        connection->setEcho(true);
        if (password == readBuffer) {
            if (database.hasPlayer(name)) {
                connection->write("Duplicate creation for same name.\n");
                return FAIL;
            }
            MudPlayer::create(database, name, password);
            state = DONE;
            return SUCCESS;
        }
        if (--retries == 0) return FAIL;
        connection->write("Passwords don't match\n");
        printPrompt();
        connection->setEcho(false);
        break;
    default:
        ASSERT_FAIL();
    }
    return INPROGRESS;
}


void PlayerCreationSession::setPrompt(const char* p) { prompt = p; }


void PlayerCreationSession::printPrompt() { connection->write(prompt.c_str()); }

